﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using WikiDoc.Formatter;
using WikiDoc.Lines;
using WikiDoc.Utils;

namespace WikiDoc.Parser
{
    /// <summary>
    /// 解析列表
    /// </summary>
    public class ListParser
    {
        /// <summary>
        /// 读取一个完整的列表，直到列表结束，退出时当前行是下一个片段起始行
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="formatter">The formatter.</param>
        public void Process(WikiReader reader, IFormatter formatter)
        {
            var listType = reader.CurrentLine.Type;

            if (listType == LineTypes.AlphaList || listType == LineTypes.BulletList|| listType == LineTypes.NumberList)
            {
                ParseList(listType, reader, formatter);
            }
        }

        /// <summary>
        /// 读取一个完整的列表，直到列表结束，退出时当前行是下一个片段起始行
        /// </summary>
        /// <param name="listType">Type of the list.</param>
        /// <param name="reader">The reader.</param>
        /// <param name="formatter">The formatter.</param>
        private static void ParseList(LineTypes listType, WikiReader reader, IFormatter formatter)
        {
            if (reader.CurrentLine.Type != listType)
            {
                return;
            }

            var level = ((ListLine) reader.CurrentLine).Level;
            var sb = new OutputBuffer();
            var keepgo = true;

            BeginList(listType, formatter);

            while (keepgo)
            {
                switch (reader.CurrentLine.Type)
                {
                    // 一个空行表示一个列表项的结束
                    case LineTypes.Empty:
                        WriteContent(sb.Flush(), formatter);

                        // 跳过后续的所有空行
                        do
                        {
                            formatter.BeginTag("br");
                            formatter.EndTag("br");
                            reader.ReadLine();
                        } while (reader.CurrentLine.Type == LineTypes.Empty);

                        break;

                        // 列表中遇到列表定义行
                        // 如果缩进级别相同，则说明是本列表的一个新列表项
                        // 如果缩进级别更高，则说明要开始一个新的下一级列表
                        // 如果缩进级别更低，则说明本列表已经结束
                    case LineTypes.BulletList:
                    case LineTypes.NumberList:
                    case LineTypes.AlphaList:
                        WriteContent(sb.Flush(), formatter);
                        var newlist = (ListLine)reader.CurrentLine;

                        if (newlist.Level > level)
                        {
                            ParseList(reader.CurrentLine.Type, reader, formatter);
                        }
                        else if (newlist.Level < level)
                        {
                            keepgo = false;
                        }
                        else
                        {
                            sb.AppendLine(((ListLine)reader.CurrentLine).Content);
                            reader.ReadLine();
                        }
                        break;

                        // 列表中遇到普通行或缩进行视为续行
                    case LineTypes.Indent:
                        sb.AppendLine(reader.CurrentLine.Line);
                        reader.ReadLine();
                        break;

                    // 其他情况，视为列表结束
                    case LineTypes.Normal:
                    default:
                        WriteContent(sb.Flush(), formatter);
                        keepgo = false;
                        break;
                }

            }

            EndList(listType, formatter);
        }

        private static void BeginList(LineTypes listType, IFormatter formatter)
        {
            switch (listType)
            {
                case LineTypes.BulletList:
                    formatter.BeginTag("ul");
                    break;
                case LineTypes.NumberList:
                    formatter.BeginTag("ol");
                    break;
                case LineTypes.AlphaList:
                    formatter.BeginTag("ol");
                    formatter.AddAttribute("type", "a");
                    break;
                case LineTypes.Indent:
                    formatter.BeginTag("ul");
                    break;
                default:
                    throw new ArgumentOutOfRangeException("listType", listType, "不是有效的列表类型");
            }
        }

        private static void WriteContent(string content, IFormatter formatter)
        {
            if (string.IsNullOrEmpty(content))
            {
                return;
            }

            content = WikiTranslater.SimpleTranslate(content);

            formatter.BeginTag("li");
            formatter.AppendContent(content);
            formatter.EndTag("li");
        }

        private static void EndList(LineTypes listType, IFormatter formatter)
        {
            switch (listType)
            {
                case LineTypes.BulletList:
                    formatter.EndTag("ul");
                    break;
                case LineTypes.NumberList:
                    formatter.EndTag("ol");
                    break;
                case LineTypes.AlphaList:
                    formatter.EndTag("ol");
                    break;
                case LineTypes.Indent:
                    formatter.EndTag("ul");
                    break;
                default:
                    throw new ArgumentOutOfRangeException("listType", listType, "不是有效的列表类型");
            }
        }

    }
}
